package com.hd123.rumba.action.qt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Transaction;

import org.apache.log4j.lf5.util.StreamUtils;

import com.hd123.rumba.cartridge.FVRumbaQt;
import com.hd123.rumba.cartridge.biz.BCartFunctionView;
import com.hd123.rumba.cartridge.biz.IBCartridgeMgr;
import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.log.RumbaLogger;
import com.hd123.rumba.qt.IQueryMgr;
import com.hd123.rumba.qt.MaxQueryException;
import com.hd123.rumba.qt.QTConstants;
import com.hd123.rumba.qt.QueryResultSession;
import com.hd123.rumba.qt.def.IQueryDef;
import com.hd123.rumba.qt.def.IQueryDefinitionMgr;
import com.hd123.rumba.qt.def.ISessionValues;
import com.hd123.rumba.qt.def.ParseException;
import com.hd123.rumba.qt.def.QueryDefinition;
import com.hd123.rumba.qt.def.SQLCheckList;
import com.hd123.rumba.qt.def.SQLColumn;
import com.hd123.rumba.qt.def.SQLColumnList;
import com.hd123.rumba.qt.def.SQLCriteria;
import com.hd123.rumba.qt.def.SQLCriteriaList;
import com.hd123.rumba.qt.def.SQLNCriteria;
import com.hd123.rumba.qt.def.SQLNCriteriaList;
import com.hd123.rumba.qt.def.SQLNCriteriaListList;
import com.hd123.rumba.qt.def.SQLOrder;
import com.hd123.rumba.qt.def.SQLOrderList;
import com.hd123.rumba.qt.html.PrintTable;
import com.hd123.rumba.qt.report.FieldDefinition;
import com.hd123.rumba.qt.report.PaperDefinition;
import com.hd123.rumba.qt.report.Report;
import com.hd123.rumba.qt.result.DisplayCriteria;
import com.hd123.rumba.qt.result.IQueryResultMgr;
import com.hd123.rumba.qt.result.QueryCriteria;
import com.hd123.rumba.qt.result.QueryResultDescription;
import com.hd123.rumba.qt.run.QueryThread;
import com.hd123.rumba.request.Action;
import com.hd123.rumba.request.ActionAbstractImpl;
import com.hd123.rumba.request.ActionConstants;
import com.hd123.rumba.request.BuffaloSession;
import com.hd123.rumba.request.Dictionary;
import com.hd123.rumba.request.ExternalRequestHandler;
import com.hd123.rumba.request.JspLib;
import com.hd123.rumba.runtime.FormatSettings;
import com.hd123.rumba.runtime.HibernateSession;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.OperateContext;
import com.hd123.rumba.sql.JdbcRow;
import com.hd123.rumba.sql.ResultPage;
import com.hd123.rumba.sql.SQLSubquery;
import com.hd123.rumba.sql.biz.BResultPage;
import com.hd123.rumba.sql.biz.BSQLSubquery;
import com.hd123.rumba.user.IUser;
import com.hd123.rumba.user.UserMgr;
import com.hd123.rumba.util.StringUtil;

public class ViewQuery extends ActionAbstractImpl implements Action, ISessionValues {

  public static final String CAPTION_VIEW = "查询";

  public static final String FUNCV_PREFIX = FVRumbaQt.FUNCV_PREFIX;
  public static final String PERMISSION_ADMINRESULTS = FUNCV_PREFIX + ".查询管理.管理查询结果";
  public static final String PERMISSION_ADMINDEFINITIONS = FUNCV_PREFIX + ".查询管理.查询定义";
  public static final String PERMISSION_FR3REPORTDESIGN = FUNCV_PREFIX + ".查询管理.设计打印格式";

  private static final String TEMPLATE_VIEW = "rumba/qt/QueryResult.jsp";
  private static final String TEMPLATE_NEXTQUERYVIEW = "rumba/qt/NextQueryResult.jsp";
  private static final String TEMPLATE_PRINT = "rumba/qt/QueryPrintResult.jsp";

  private static final String TEMPLATE_QUERYDEFLIST = "rumba/qt2/QueryDefList.jsp";
  private static final String TEMPLATE_QUERYDEFCREATE = "rumba/qt2/QueryDefCreate.jsp";

  private static final String TEMPLATE_QUERYLIST = "rumba/qt2/QueryList.jsp";

  private static final String TEMPLATE_MYQUERYSLIST = "rumba/qt2/MyQuerysList.jsp";
  private static final String TEMPLATE_MYQUERYSFILTER = "rumba/qt2/MyQuerysFilter.jsp";
  private static final String TEMPLATE_ALLQUERYSLIST = "rumba/qt2/AllQuerysList.jsp";
  private static final String TEMPLATE_ALLQUERYSFILTER = "rumba/qt2/AllQuerysFilter.jsp";

  private static final String TEMPLATE_PRINTOPTIONS = "rumba/qt2/QueryPrintOptions.jsp";

  public String execute() throws Exception {
    String startnode = (String) dd.getFormValue("start");
    String url = ActionConstants.NOTIMPLEMENTED;
    if (startnode == null)
      startnode = "list";
    if (startnode.equals("list"))
      url = executeWithPermission("list", null);
    else if (startnode.equals("myquerysList"))
      url = executeWithPermission("myquerysList", null);
    else if (startnode.equals("allquerysList"))
      url = executeWithPermission("allquerysList", PERMISSION_ADMINRESULTS);
    else if ("filterMyQuerys".equals(startnode))
      url = this.executeWithPermission("filterMyQuerys", null);
    else if ("filterAllQuerys".equals(startnode))
      url = this.executeWithPermission("filterAllQuerys", null);
    else if (startnode.equals("view"))
      url = executeWithPermission("view", null);
    else if (dd.getFormValues().containsKey("query"))
      url = executeWithPermission("query", null);
    else if (dd.getFormValues().containsKey("allquery"))
      url = executeWithPermission("allquery", PERMISSION_ADMINRESULTS);
    else if (startnode.equals("nextQuery"))
      url = executeWithPermission("nextQuery", PERMISSION_ADMINRESULTS);
    else if (startnode.equals("print"))
      url = executeWithPermission("print", null);
    else if ("listDef".equals(startnode))
      url = this.executeWithPermission("listDef", ViewQuery.PERMISSION_ADMINDEFINITIONS);
    else if ("createDef".equals(startnode))
      url = this.executeWithPermission("createDef", ViewQuery.PERMISSION_ADMINDEFINITIONS);
    else if ("viewDef".equals(startnode))
      url = this.executeWithPermission("viewDef", ViewQuery.PERMISSION_ADMINDEFINITIONS);
    else if ("printOptions".equals(startnode))
      url = this.executeWithPermission("printOptions", null);
    else if (startnode.equals("dispatch")) {
      url = executeWithPermission("prepareMultipart", null);
      if (url != null)
        return url;
      String action = (String) dd.getFormValue("action");
      if ("saveDef".equals(action))
        url = executeWithPermission("saveDef", PERMISSION_ADMINDEFINITIONS);
      else if (dd.getFormValues().containsKey("list"))
        url = executeWithPermission("list", null);
      else if (dd.getFormValues().containsKey("myquerysList"))
        url = myquerysList();
      else if (dd.getFormValues().containsKey("allquerysList"))
        url = executeWithPermission("allquerysList", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("query"))
        url = executeWithPermission("query", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("view"))
        url = executeWithPermission("view", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("confirm"))
        url = executeWithPermission("confirm", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("cancelQuery"))
        url = executeWithPermission("cancelQuery", null);
      else if (dd.getFormValues().containsKey("resultQuery"))
        url = executeWithPermission("resultQuery", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("allquery"))
        url = executeWithPermission("allquery", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("saveDef"))
        url = executeWithPermission("saveDef", PERMISSION_ADMINDEFINITIONS);
      else if (dd.getFormValues().containsKey("myquerysReturn"))
        url = executeWithPermission("myquerysReturn", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("allquerysReturn"))
        url = executeWithPermission("allquerysReturn", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("resultsReturn"))
        url = executeWithPermission("resultsReturn", null);
      else if (dd.getFormValues().containsKey("returnMenu"))
        url = executeWithPermission("returnMenu", null);
      else if (dd.getFormValues().containsKey("returnTreeView"))
        url = executeWithPermission("returnTreeView", null);
      else if (dd.getFormValues().containsKey("nextQuery")
          && (dd.getFormValue("nextQuery_uuid") != null && ((String) dd
              .getFormValue("nextQuery_uuid")).length() > 0))
        url = executeWithPermission("nextQuery", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("refurbish"))
        url = executeWithPermission("refurbish", PERMISSION_ADMINRESULTS);
      else if (dd.getFormValues().containsKey("nextResultQuery"))
        url = executeWithPermission("nextResultQuery", PERMISSION_ADMINRESULTS);
      else
        url = paging();
    }
    return url;
  }

  private static IQueryMgr queryMgr = null;
  private static IQueryResultMgr queryResultMgr = null;
  private static IQueryDefinitionMgr queryDefMgr = null;

  public IQueryMgr getQueryMgr() throws BusinessException {
    if (queryMgr == null)
      queryMgr = (IQueryMgr) NamingMgr.getInstance().lookupMgr(IQueryMgr.class);
    return queryMgr;
  }

  public IQueryResultMgr getResultMgr() throws BusinessException {
    if (queryResultMgr == null)
      queryResultMgr = (IQueryResultMgr) NamingMgr.getInstance().lookupMgr(IQueryResultMgr.class);
    return queryResultMgr;
  }

  public IQueryDefinitionMgr getDefinitionMgr() throws BusinessException {
    if (queryDefMgr == null)
      queryDefMgr = (IQueryDefinitionMgr) NamingMgr.getInstance().lookupMgr(
          IQueryDefinitionMgr.class);
    return queryDefMgr;
  }

  public String prepareMultipart() throws IOException {
    return null;
  }

  /**
   * 有三种情况下都会调用此方法:
   * <li>查询尚未开始执行. 此时, 返回的页面显示默认的查询条件和以往的查询结果. 显示"查询"按钮.
   * <li>查询正在执行中. 此时, 返回的页面显示正在执行的查询条件, 以及"正在执行"的提示, 和以往的查询结果. 不显示"查询"按钮.
   * 
   * @return
   * @throws Exception
   */
  public String list() throws Exception {
    String base = QTConstants.QDHOME;
    String query_uuid = (String) dd.getFormValue("query_uuid");
    IQueryDef queryDef = getDefinitionMgr().getQueryDef(query_uuid);
    if (queryDef == null)
      throw new Exception("找不到指定的查询定义(uuid=" + query_uuid + ")。");
    if (!queryDef.getFile().exists())
      throw new Exception("该查询定义文件不存在, 可能已被删除!");

    // 处理mdx查询
    LineNumberReader fileReader = new LineNumberReader(new FileReader(queryDef.getFile()));
    String line = fileReader.readLine();
    if ("mdx-redirect".equalsIgnoreCase(line)) {
      String url = JspLib.getAction("..") + fileReader.readLine();
      System.out.println("!!!" + url);
      // 使用客户端重定向功能, 以激发ViewCube上的filter
      dd.getResponse().setCharacterEncoding(StringUtil.ENCODING_CHARSET);
      dd.getResponse().setContentType("text/html");
      ServletOutputStream out = dd.getResponse().getOutputStream();
      StringBuffer sb = new StringBuffer();
      sb.append("<html>");
      sb.append("<script language='javascript'>");
      sb.append("window.navigate('");
      sb.append(url);
      sb.append("');");
      sb.append("</script>");
      sb.append("</html>");
      out.write(sb.toString().getBytes(), 0, sb.toString().getBytes().length);
      dd.getResponse().setContentLength(sb.toString().getBytes().length);
      out.flush();

      return ActionConstants.DIRECT;
    }

    String qrd_uuid = (String) dd.getFormValue("qrd_uuid");
    String returnH = "resultsReturn";
    dd.put("queryDef", queryDef);
    dd.putFormValue("returnH", returnH);
    dd.putFormValue("qrd_uuid", qrd_uuid);

    prepareCondition();
    prepareTables();
    // 设置正在执行中的qrd_uuid
    List<QueryResultDescription> qrds = (List<QueryResultDescription>) dd.get("runningQrds");
    if (qrds != null && qrds.size() > 0) {
      dd.putFormValue("qrd_uuid", qrds.get(0).getUuid());
      dd.put("qrd", qrds.get(0));
    }
    dd.setWorkingTemplate(TEMPLATE_QUERYLIST);
    return ActionConstants.APPLICATIONFRAME;
  }

  public void prepareCondition() throws Exception {
    String query_uuid = (String) dd.getFormValue("query_uuid");
    IUser user = (IUser) getCurrentUser();
    String hint = (String) dd.getFormValue("hint");
    String error = (String) dd.getFormValue("error");
    String qrd_uuid = (String) dd.getFormValue("qrd_uuid");
    if (hint != null && !hint.equals("null"))
      dd.addHint(hint);
    if (error != null && !error.equals("null"))
      dd.addErrorText(error);
    String returnH = "resultsReturn";
    IQueryDef queryDef = getDefinitionMgr().getQueryDef(query_uuid);
    QueryResultDescription qrd111 = null;
    if (qrd_uuid != null && qrd_uuid.length() > 0)
      qrd111 = getResultMgr().findQrdByUuid(qrd_uuid);
    QueryResultDescription qrd = getQueryMgr().openQuery(queryDef, new OperateContext(user));
    QueryCriteria queryCriteria = null;
    DisplayCriteria displayCriteria = null;
    if (qrd111 != null) {
      qrd.getQueryCriteria().setSg(qrd111.getQueryCriteria().getSg());
      qrd.setDisplayCriteria(qrd111.getDisplayCriteria());
    }
    queryCriteria = qrd.getQueryCriteria();
    queryCriteria.getQuery().setSessionValues(this);
    displayCriteria = qrd.getDisplayCriteria();
    // 以下是勾选表的一部分
    SQLCheckList scl = queryCriteria.getQuery().getChecks();
    // 勾选表
    SQLColumnList columns = (SQLColumnList) qrd.getQuery().getColumns();
    Object[] orderSelection = createOrders(columns);
    setPickValues(queryCriteria);
    SQLOrderList orders = (SQLOrderList) displayCriteria.getOrders();
    setOrderValues(orders);
    dd.putFormValue("returnH", returnH);
    dd.put("orderSelection", orderSelection);
    dd.put("queryCriteria", queryCriteria);
    dd.put("displayCriteria", displayCriteria);
    dd.put("sqlCheckList", scl);
    dd.put("theQrd", qrd);
    dd.putFormValue("query_uuid", query_uuid);
    dd.putFormValue("qrd_uuid", qrd_uuid);
  }

  /**
   * 如果当前用户正在执行名为query_uuid的查询, 则返回其执行时间(毫秒). 否则返回-1.
   * 由QuerysTable.jspf以xmlhttp方式同步调用.
   * 
   * @param query_uuid
   * @return
   * @throws Exception
   */
  public long getQueryRunningTime(String query_uuid) throws Exception {
    long time = -1;
    List<QueryResultDescription> list = getResultMgr().findRunningQueries(
        BuffaloSession.getCurrentUser(), query_uuid);
    if (list != null && list.size() > 0) {
      time = new Date().getTime() - list.get(0).getStartTime().getTime();
    }
    return time;
  }

  /**
   * 查找指定用户和查询名称的qrds, 按正在运行中和已完成两种状态以Key=running*和runOver*存入dd.formValues中.
   * 
   * @throws Exception
   */
  public void prepareTables() throws Exception {
    String query_uuid = (String) dd.getFormValue("query_uuid");
    List qrds = getResultMgr().findAllResults(getCurrentUser(), query_uuid);
    List runningQrds = new ArrayList();
    List runOverQrds = new ArrayList();
    for (int i = 0; i < qrds.size(); i++) {
      QueryResultDescription qrd1 = (QueryResultDescription) qrds.get(i);
      if (qrd1.getResultCount().equals(QueryResultDescription.RESULTCOUNT_RUNNING))
        runningQrds.add(qrd1);
      else
        runOverQrds.add(qrd1);
    }
    dd.put("runningQrds", runningQrds);
    dd.put("runOverQrds", runOverQrds);
    if (runningQrds != null && runningQrds.size() > 0)
      dd.put("runningQrd", runningQrds.get(0));
  }

  /**
   * @return
   * @throws Exception
   */
  public String query() throws Exception {
    setSessionValues();
    QueryResultDescription qrd = null;
    String query_uuid = (String) dd.getFormValue("query_uuid");
    if (query_uuid == null)
      throw new BusinessException("缺少必要的参数query_uuid。");
    IUser user = (IUser) getCurrentUser();
    Hashtable h = new Hashtable();
    h = dd.getFormValues();
    dd.validateFormValue(DisplayCriteria.PARAM_ROWS_PER_PAGE_KEY, "Integer", false, null, "每页记录数");
    if (!dd.isFormValid()) {
      dd.addErrorText("每页记录数请输入整数!");
      return list();
    }
    IQueryDef queryDef = getDefinitionMgr().getQueryDef(query_uuid);
    qrd = getQueryMgr().findQueryResult(queryDef, user, h);
    try {
      if (qrd != null) {
        QueryDefinition qd = getDefinitionMgr().getQueryDefinition(qrd);
        qrd.setQuery(qd);
        qrd.setCriteria(h);
        getQueryMgr().executeQuery(qrd, this);
      } else
        qrd = getQueryMgr().executeQuery(queryDef, this, h);
      dd.put("KeepQuerySourceAndResultSessions", "true");
      QueryThread queryThread = qrd.getQueryThread();
      queryThread.join(QTConstants.MAXWAITTIME);
      QueryResultDescription qqrd = (QueryResultDescription) HibernateSession.getSession().load(
          qrd.getClass(), qrd.getUuid());
      qqrd.setDisplayCriteria(qrd.getDisplayCriteria());
      if (qqrd.getResultCount().intValue() < 0) {
        dd.putFormValue("qrd_uuid", qqrd.getUuid());
        if (qqrd.getResultCount().equals(QueryResultDescription.RESULTCOUNT_ERROR))
          dd.addErrorText("错误:" + qqrd.getMessage());
        return list();
      } else {
        dd.putFormValue("qrd_uuid", qqrd.getUuid());
        return view();
      }
    } catch (MaxQueryException e) {
      dd.addErrorText("服务器正忙(已达到最大并发查询数), 请稍后再试.");
      return list();
    } catch (HibernateException e) {
      dd.addErrorText("无法连接数据库");
      return list();
    }
  }

  public String allquery() throws Exception {
    dd.putFormValue("pageInfo_id", "allquerys");
    dd.putFormValue("PageNumber_0", "0");
    return paging();
  }

  public String resultQuery() throws Exception {
    return resultQueryInternal(0, 0, 0);
  }

  /**
   * 返回查询页面的时候, 使用method=0, 被resultQuery()调用 返回打印页面的时候, 使用method=1, start,
   * limit. 被print()调用.
   * 
   * @param method
   * @param start
   * @param limit
   * @return
   * @throws Exception
   */
  protected String resultQueryInternal(int method, int start, int limit) throws Exception {
    String qrd_uuid = (String) dd.getFormValue("qrd_uuid");
    String base = QTConstants.QDHOME;
    QueryResultDescription qrd1 = getResultMgr().findQrdByUuid(qrd_uuid);
    String query_name = qrd1.getQdName();
    QueryDefinition qd = getDefinitionMgr().getQueryDefinition(qrd1);
    SQLColumnList columns = (SQLColumnList) qd.getColumns();
    List visibleColumns = columns.getVisibleColumns();
    List names = columns.getResultTableVisibleColumnNames();
    qrd1.setQuery(qd);
    qrd1.setCriteria(dd.getFormValues());
    Object[] orderSelection = createOrders(columns);
    QueryCriteria queryCriteria = qrd1.getQueryCriteria();
    DisplayCriteria displayCriteria = qrd1.getDisplayCriteria();
    List results = new ArrayList();
    ResultPage rp = method == 0 ? getQueryMgr().getResult(base, qrd1.getUuid(), 0) : getQueryMgr()
        .getResult(base, qrd1.getUuid(), start, limit);
    if (rp.getPageCount() != 0) {
      results = rp.getContentList();
    }
    List summary = new ArrayList();
    ResultPage summaryrp = getQueryMgr().getSummary(base, qrd1.getUuid());
    if (rp.getPageCount() != 0 && summaryrp != null)
      summary = summaryrp.getContentList();

    // 以下是下一查询的部分
    SQLNCriteriaListList nextQuerys = qd.getNcriterias();
    String nextQuery_name = null;
    List nextQueryNames = new ArrayList();
    if (nextQuerys.size() > 0) {
      for (int i = 0; i < nextQuerys.size(); i++) {
        SQLNCriteriaList nextQuery = (SQLNCriteriaList) nextQuerys.get(i);
        nextQuery_name = nextQuery.getNextQuery();
        nextQueryNames.add(nextQuery_name);
      }
    }
    // 以上是下一查询的部分
    rp.setId("results");
    dd.put("nextQueryNames", nextQueryNames);
    dd.putFormValue("query_name", dd.getFormValue("query_name"));
    dd.putFormValue("qrd_uuid", qrd1.getUuid());
    dd.put("orderSelection", orderSelection);
    dd.put("visibleColumns", visibleColumns);
    dd.put("names", names);
    dd.put("queryCriteria", queryCriteria);
    dd.put("displayCriteria", displayCriteria);
    dd.put("results", results);
    dd.put("summary", summary);
    dd.putFormValue("pageInfo_id", "allquerys");
    dd.put("pageInfo", rp);
    dd.put("qrd", qrd1);
    dd.put("queryPath", new QueryPath(dd));
    Transaction tx = HibernateSession.beginTransaction();
    try {
      getResultMgr().saveQrd(qrd1);
      HibernateSession.commit(tx);
    } catch (HibernateException e) {
      HibernateSession.rollback(tx);
      throw e;
    }
    dd.put("onBodyLoad", "prepareProgress()");
    setDDValuesForRptServer(qrd1);
    dd.setWorkingTemplate(TEMPLATE_VIEW);
    return ActionConstants.APPLICATIONFRAME;
  }

  public String nextResultQuery() throws Exception {
    String qrd_uuid = (String) dd.getFormValue("qrd_uuid");
    String base = QTConstants.QDHOME;
    QueryResultDescription qrd1 = getResultMgr().findQrdByUuid(qrd_uuid);
    String query_name = qrd1.getQdName();
    QueryDefinition qd = getDefinitionMgr().getQueryDefinition(qrd1);
    SQLColumnList columns = (SQLColumnList) qd.getColumns();
    List titles = columns.getVisibleColumnTitles();
    List names = columns.getResultTableVisibleColumnNames();
    String rowsPerPage = (String) dd.getFormValue("rowsPerPage");
    Integer rpp = new Integer(rowsPerPage);
    qrd1.getDisplayCriteria().setRowsPerPage(rpp);
    qrd1.setQuery(qd);
    qrd1.setCriteria(dd.getFormValues());
    Object[] orderSelection = createOrders(columns);
    QueryCriteria queryCriteria = qrd1.getQueryCriteria();
    queryCriteria.getQuery().setSessionValues(this);
    DisplayCriteria displayCriteria = qrd1.getDisplayCriteria();
    List results = new ArrayList();
    ResultPage rp = getQueryMgr().getResult(base, qrd1.getUuid(), 0);
    if (rp.getPageCount() != 0) {
      results = rp.getContentList();
    }
    List summary = new ArrayList();
    ResultPage summaryrp = getQueryMgr().getSummary(base, qrd1.getUuid());
    if (rp.getPageCount() != 0 && summaryrp != null)
      summary = summaryrp.getContentList();
    rp.setId("results");
    dd.putFormValue("query_name", dd.getFormValue("query_name"));
    dd.putFormValue("qrd_uuid", qrd1.getUuid());
    dd.put("orderSelection", orderSelection);
    dd.put("titles", titles);
    dd.put("names", names);
    dd.put("queryCriteria", queryCriteria);
    dd.put("displayCriteria", displayCriteria);
    dd.put("results", results);
    dd.put("summary", summary);
    dd.putFormValue("pageInfo_id", "allquerys");
    dd.put("pageInfo", rp);
    Transaction tx = HibernateSession.beginTransaction();
    try {
      getResultMgr().saveQrd(qrd1);
      HibernateSession.commit(tx);
    } catch (HibernateException e) {
      HibernateSession.rollback(tx);
      throw e;
    }
    dd.setWorkingTemplate(TEMPLATE_NEXTQUERYVIEW);
    return ActionConstants.APPLICATIONFRAME;

  }

  public String confirm() throws Exception {
    String qrd_uuid = (String) dd.getFormValue("qrd_uuid");
    String query_name = (String) dd.getFormValue("query_name");
    String query_uuid = (String) dd.getFormValue("query_uuid");
    String base = QTConstants.QDHOME;
    Hashtable h = new Hashtable();
    h.putAll(dd.getFormValues());
    IQueryDef queryDef = getDefinitionMgr().getQueryDef(query_uuid);
    QueryResultDescription qrd = new QueryResultDescription();
    try {
      qrd = getQueryMgr().executeQuery(queryDef, this, h);
      dd.put("KeepQuerySourceAndResultSessions", "true");
      QueryThread queryThread = qrd.getQueryThread();
      queryThread.join(QTConstants.MAXWAITTIME);
      QueryResultDescription qqrd = (QueryResultDescription) HibernateSession.getSession().load(
          qrd.getClass(), qrd.getUuid());
      Transaction tx = HibernateSession.beginTransaction();
      try {
        QueryResultDescription qrd1 = getResultMgr().findQrdByUuid(qrd_uuid);
        getResultMgr().removeQrd(qrd1);
        HibernateSession.commit(tx);
      } catch (HibernateException e) {
        HibernateSession.rollback(tx);
        throw e;
      }
      if (qqrd.getResultCount().equals(QueryResultDescription.RESULTCOUNT_RUNNING)) {
        return list();
      } else {
        dd.putFormValue("qrd_uuid", qrd.getUuid());
        return view();
      }
    } catch (MaxQueryException e) {
      dd.addErrorText("已达到最大查询数");
      return list();
    } catch (HibernateException e) {
      dd.addErrorText("没有连上数据库");
      return list();
    }
  }

  public String view() throws Exception {
    if (!dd.getFormValues().containsKey("pageSpecified"))
      dd.putFormValue("PageNumber_0", "0");
    dd.putFormValue("pageInfo_id", "results");
    return paging();
  }

  public String myquerysList() throws Exception {
    QueryResultFilter filter = getQueryResultFilter();
    dd.put("filter", filter);
    dd.setWorkingTemplate(TEMPLATE_MYQUERYSLIST);
    return ActionConstants.APPLICATIONFRAME;
  }

  public String allquerysList() throws Exception {
    QueryResultFilter filter = getQueryResultFilter();
    dd.put("filter", filter);
    dd.setWorkingTemplate(TEMPLATE_ALLQUERYSLIST);
    return ActionConstants.APPLICATIONFRAME;
  }

  protected String paging(int page) throws Exception {
    String result = "";
    if ("results".equals(dd.getFormValue("pageInfo_id")))
      result = resultsPaging(page);
    return result;
  }

  public String resultsPaging(int page) throws Exception {
    QueryPath queryPath = new QueryPath(dd);
    dd.put("queryPath", queryPath);

    String qrd_uuid = (String) dd.getFormValue("qrd_uuid");
    String base = QTConstants.QDHOME;
    QueryResultDescription qrd = (QueryResultDescription) getResultMgr().findQrdByUuid(qrd_uuid);
    dd.putFormValue("query_uuid", qrd.getQdUuid());
    if (qrd.getResultCount().intValue() == QueryResultDescription.RESULTCOUNT_ERROR.intValue()) {
      dd.addErrorText("错误:" + qrd.getMessage());
      return list();
    } else if (qrd.getResultCount().intValue() == QueryResultDescription.RESULTCOUNT_CANCEL
        .intValue()) {
      dd.addHint("查询被取消.");
      return list();
    }
    IQueryDef queryDef = getDefinitionMgr().getQueryDef(qrd.getQdUuid());
    String query_name = qrd.getQdName();
    QueryDefinition qd = getDefinitionMgr().getQueryDefinition(qrd);
    // 接下来是下一查询的部分
    SQLNCriteriaListList nextQuerys = qd.getNcriterias();
    Object[] nextQuerysSelection = new Object[nextQuerys.size() * 3];
    String nextQuery_name = null;
    List nextQueryNames = new ArrayList();
    if (nextQuerys.size() > 0) {
      for (int i = 0; i < nextQuerys.size(); i++) {
        SQLNCriteriaList nextQuery = (SQLNCriteriaList) nextQuerys.get(i);
        nextQuery_name = nextQuery.getNextQuery();
        nextQueryNames.add(nextQuery_name);
      }
    }
    // 以上是下一查询的部分
    qrd.setQuery(qd);
    SQLColumnList columns = (SQLColumnList) qd.getColumns();
    List names = columns.getResultTableVisibleColumnNames();
    List visibleColumns = columns.getVisibleColumns();
    Object[] orderSelection = createOrders(columns);
    QueryCriteria queryCriteria = qrd.getQueryCriteria();
    queryCriteria.getQuery().setSessionValues(this);
    DisplayCriteria displayCriteria = qrd.getDisplayCriteria();
    List results = new ArrayList();
    ResultPage rp = getQueryMgr().getResult(qrd, page);
    if (rp.getPageCount() != 0) {
      results = rp.getContentList();
    }
    List summary = new ArrayList();
    ResultPage summaryrp = getQueryMgr().getSummary(qrd);
    if (rp.getPageCount() != 0 && summaryrp != null)
      summary = summaryrp.getContentList();

    String returnH = (String) dd.getFormValue("returnH");
    rp.setId("results");
    dd.putFormValue("query_uuid", queryDef.getUuid());
    dd.put("nextQueryNames", nextQueryNames);
    dd.put("nextQuerysSelection", nextQuerysSelection);
    dd.putFormValue("query_name", query_name);
    dd.putFormValue("qrd_uuid", qrd_uuid);
    dd.putFormValue("returnH", returnH);
    dd.put("orderSelection", orderSelection);
    dd.put("visibleColumns", visibleColumns);
    dd.put("names", names);
    dd.put("queryCriteria", queryCriteria);
    dd.put("displayCriteria", displayCriteria);
    dd.put("results", results);
    dd.put("summary", summary);
    dd.put("pageInfo", rp);
    dd.put("qrd", qrd);
    dd.put("onBodyLoad", "prepareProgress()");
    setDDValuesForRptServer(qrd);

    dd.setWorkingTemplate(TEMPLATE_VIEW);
    return ActionConstants.APPLICATIONFRAME;
  }

  private void setDDValuesForRptServer(QueryResultDescription qrd) {
    String rptFileName = qrd.getQdName().replace(".sql", ".fr3");
    File rptFile = new File(QTConstants.QDHOME, rptFileName);
    if (!rptFile.exists())
      return;
    dd.put("rptServer", "true");
  }

  public SQLSubquery genMyQuerysSQLSubqueryByConditon() throws Exception {
    String state = (String) dd.getFormValue("cond_state");
    SQLSubquery sq = new SQLSubquery();
    sq.addSelect("qrd");
    sq.addFrom("QueryResultDescription qrd");
    sq.addWhere("qrd.userUuid=?", getCurrentUser().getUuid());
    sq.addWhere("and qrd.qdName like ?", dd.getFormValue("cond_qdName"), SQLSubquery.WC_BOTH);
    if (state != null) {
      if (state.equals("执行中"))
        sq.addWhere("and qrd.resultCount=-1");
      else if (state.equals("已完成"))
        sq.addWhere("and qrd.resultCount>0");
    }
    sq.addWhere("and qrd.startTime >= ?", dd.getValidFormValues().get("cond_startTimeFrom"));
    sq.addWhere("and qrd.startTime < ?", StringUtil.addDate((Date) dd.getValidFormValues().get(
        "cond_startTimeTo"), Calendar.DATE, 1));
    String sortField1 = (String) dd.getFormValue("cond_sort_field1");
    if (sortField1 == null)
      sortField1 = "qrd.startTime";
    String sortOrder1 = (String) dd.getFormValue("cond_sort_order1");
    if (sortOrder1 == null)
      sortOrder1 = "desc";
    String sortField2 = (String) dd.getFormValue("cond_sort_field2");
    if (sortField2 == null)
      sortField2 = "qrd.qdName";
    String sortOrder2 = (String) dd.getFormValue("cond_sort_order2");
    if (sortOrder2 == null)
      sortOrder2 = "asc";
    sq.addOrder(sortField1, sortOrder1);
    sq.addOrder(sortField2, sortOrder2);
    return sq;
  }

  public SQLSubquery genAllQuerysSQLSubqueryByConditon() throws Exception {
    String state = (String) dd.getFormValue("cond_state");
    UserMgr um = new UserMgr();
    String login = (String) dd.getFormValue("cond_user");
    SQLSubquery sq = new SQLSubquery();
    sq.addSelect("qrd");
    sq.addFrom("QueryResultDescription qrd");
    sq.addWhere("1=1");
    if (login != null && login.length() > 0) {
      IUser user = (IUser) um.getUserByLogin(getCurrentDomain(), login);
      if (user != null)
        sq.addWhere("and qrd.userUuid=?", user.getUuid());
    }
    sq.addWhere("and qrd.qdName like ?", dd.getFormValue("cond_qdName"), SQLSubquery.WC_BOTH);
    if (state != null) {
      if (state.equals("执行中"))
        sq.addWhere("and qrd.resultCount=-1");
      else if (state.equals("已完成"))
        sq.addWhere("and qrd.resultCount>0");
    }
    sq.addWhere("and qrd.startTime >= ?", dd.getValidFormValues().get("cond_startTimeFrom"));
    sq.addWhere("and qrd.startTime < ?", StringUtil.addDate((Date) dd.getValidFormValues().get(
        "cond_startTimeTo"), Calendar.DATE, 1));
    String sortField1 = (String) dd.getFormValue("cond_sort_field1");
    if (sortField1 == null)
      sortField1 = "qrd.qdName";
    String sortOrder1 = (String) dd.getFormValue("cond_sort_order1");
    if (sortOrder1 == null)
      sortOrder1 = "desc";
    String sortField2 = (String) dd.getFormValue("cond_sort_field2");
    if (sortField2 == null)
      sortField2 = "qrd.qdName";
    String sortOrder2 = (String) dd.getFormValue("cond_sort_order2");
    if (sortOrder2 == null)
      sortOrder2 = "desc";
    sq.addOrder(sortField1, sortOrder1);
    sq.addOrder(sortField2, sortOrder2);
    return sq;
  }

  public String cancelQuery() throws Exception {
    String qrd_uuid = (String) dd.getFormValue("qrd_uuid");
    Transaction tx = HibernateSession.beginTransaction();
    try {
      getQueryMgr().cancelQuery(qrd_uuid);
      tx.commit();
    } catch (HibernateException e) {
      tx.rollback();
      RumbaLogger.getLogger(this.getClass()).error(e);
      throw e;
    }
    dd.addHint("查询已取消.");
    return list();
  }

  public Object[] createOrders(SQLColumnList columns) {
    List titles = columns.getVisibleColumnTitles();
    List names = columns.getResultTableVisibleColumnNames();
    Object[] orderSelection = new Object[titles.size() * 3];
    for (int j = 0; j < titles.size(); ++j) {
      orderSelection[j * 3] = "option";
      orderSelection[j * 3 + 1] = names.get(j);// value
      orderSelection[j * 3 + 2] = titles.get(j);
    }
    return orderSelection;
  }

  public void setOrderValues(SQLOrderList orders) {
    for (int i = 0; i < orders.size(); i++) {
      SQLOrder so = (SQLOrder) orders.get(i);
      dd.putFormValue(DisplayCriteria.PARAM_SORT_COLUMN_PREFIX + i, so.getQuery() == null ? so
          .getColumn() : so.getQuery().getColumns().getResultTableColumnNameByColumnTitle(
          so.getColumn()));
      dd.putFormValue(DisplayCriteria.PARAM_SORT_ORDER_PREFIX + i, so.getOrder());
    }
  }

  public void setPickValues(QueryCriteria queryCriteria) {
    SQLCriteriaList sCriterias = queryCriteria.getQuery().getCriterias();
    String[][] sg = queryCriteria.getSg();
    int colCount = sg[0].length;
    for (int i = 1; i < 5; i++) {
      for (int j = 0; j < colCount; j++) {
        int count = 0;
        /** ***********预设条件的bug*********** */
        if (j >= sCriterias.size())
          continue;
        /** ********************************* */
        count = ((SQLCriteria) sCriterias.get(j)).getPickNames().size();
        if (count > 0)
          dd.putFormValue(QueryCriteria.PARAM_QUERY_PREFIX + i + "." + j, sg[i][j]);
      }
    }
  }

  public String myquerysReturn() throws Exception {
    return myquerysList();
  }

  public String allquerysReturn() throws Exception {
    return allquerysList();
  }

  public String resultsReturn() throws Exception {
    return list();
  }

  public String returnMenu() throws Exception {
    return returnTreeView();
  }

  public String returnTreeView() throws Exception {
    NavDefinitions nd = new NavDefinitions();
    dd.putFormValue("start", "listTreeView");
    nd.init(dd);
    return nd.execute();
  }

  // 以下是下一查询的部分
  /**
   * ajax 同步调用
   * 
   * @params 用数组表示的Hashtable<String,String>. 偶数下标为key, 奇数下标为value
   * @return
   * @throws Exception
   */
  public QueryState nextQuery(String[] params) throws Exception {
    setSessionValues();
    Hashtable<String, String> formValues = new Hashtable();
    for (int i = 0; i < params.length; i += 2) {
      formValues.put(params[i], params[i + 1]);
    }
    QueryState result = new QueryState();
    String base = QTConstants.QDHOME;
    String uuid = formValues.get("nextQuery_uuid"); // 本次查询结果选中行的uuid
    String qrd_uuid = formValues.get("qrd_uuid");
    String nextQuery_name = formValues.get("nextQuery");
    QueryResultDescription qrd = getResultMgr().findQrdByUuid(qrd_uuid);
    IQueryDef queryDef = getDefinitionMgr().getQueryDef(qrd.getQdUuid());
    QueryDefinition qd = getDefinitionMgr().getQueryDefinition(qrd);
    SQLNCriteriaListList nextQuerys = qd.getNcriterias();
    SQLNCriteriaList nextQuery = (SQLNCriteriaList) nextQuerys.get(0);
    for (int i = 0; i < nextQuerys.size(); ++i) {
      nextQuery = (SQLNCriteriaList) nextQuerys.get(i);
      if (nextQuery_name.equals(nextQuery.getNextQuery()))
        break;
    }
    // 以下是找到某条记录
    JdbcRow row = getResultMgr().findResultRow(qrd, uuid);
    IQueryDef nextQueryDef = getDefinitionMgr().getNextQueryDefByName(queryDef, nextQuery_name);
    if (nextQueryDef == null) {
      result.state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
      result.errorMessage = "下一查询定义文件" + nextQuery_name + "不存在.";
      return result;
    }
    // 设置查询条件
    QueryResultDescription nQqrd = getQueryMgr().openQuery(nextQueryDef,
        new OperateContext(getCurrentUser()));
    QueryCriteria queryCriteria = nQqrd.getQueryCriteria();
    queryCriteria.getQuery().setSessionValues(this);
    qrd.setQuery(qd);
    SQLColumnList columns = (SQLColumnList) qrd.getQuery().getColumns();
    List titles = columns.getVisibleColumnTitles();
    List names = columns.getResultTableVisibleColumnNames();
    Hashtable h = nQqrd.getCriteria();
    int colCount = queryCriteria.getSg()[0].length;
    List items = nextQuery.getItems();
    for (int i = 0; i < items.size(); i++) {
      SQLNCriteria sn = (SQLNCriteria) items.get(i);
      String left = sn.getLeft();
      String right = sn.getRight();
      boolean useColumnValueAsCondition = false;
      // try to find a column value as condition
      for (int j = 0; j < titles.size(); j++) {
        if (titles.get(j).equals(right)) {
          right = (String) names.get(j);
          right = row.get(right).toString();
          useColumnValueAsCondition = true;
          break;
        }
      }
      // try to find a query criteria value as condition
      // assume sg[0] is the title line, sg[1] is the value line
      if (!useColumnValueAsCondition) {
        String[][] sg = qrd.getQueryCriteria().getSg();
        for (int j = 0; j < sg[0].length; ++j) {
          if (right.equals(sg[0][j])) {
            right = sg[1][j];
            break;
          }
        }
      }
      for (int k = 0; k < colCount; k++) {
        String column = (String) h.get(QueryCriteria.PARAM_QUERY_PREFIX + "0." + k);
        if (left.equals(column)) {
          h.put(QueryCriteria.PARAM_QUERY_PREFIX + "1." + k, right);
          break;
        }
      }
    }
    // 进行下一查询
    QueryResultDescription qrd1 = getQueryMgr().findQueryResult(nextQueryDef, getCurrentUser(), h);
    try {
      if (qrd1 == null) {
        qrd1 = getQueryMgr().executeQuery(nextQueryDef, this, h);
      }
      result = getQueryState(qrd1.getUuid());
    } catch (MaxQueryException e) {
      result.state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
      result.errorMessage = "服务器忙(已达到最大查询数), 请稍后再试.";
    } catch (HibernateException e) {
      result.state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
      result.errorMessage = "无法连接数据库.";
    }
    return result;
  }

  public static class QueryPath extends ArrayList<PathItem> {
    String pathQrdUuidPrefix = "pathQrdUuid_";
    String pathNamePrefix = "pathName_";
    String pathPagingNumberPrefix = "pathPagingNumber_";

    public QueryPath(Dictionary dd) {
      Iterator<String> keys = dd.createFormPrefixedKeysIterator(pathQrdUuidPrefix);
      // 看看有多少path. path prefix _ 后总是从0开始的连续的整数.
      int pathCount = 0;
      while (keys.hasNext()) {
        ++pathCount;
        keys.next();
      }
      if (pathCount > 0) {
        // 回退查看的时候, 只添加到指定路径的索引, 不添加所有的pathitem
        String s = (String) dd.getFormValue("pathIndexToView");
        if (s != null && s.length() > 0) {
          int i = Integer.parseInt(s);
          if (pathCount > i)
            pathCount = i;
        }
        for (int i = 0; i < pathCount; ++i) {
          PathItem path = new PathItem();
          path.qrdUuid = (String) dd.getFormValue(pathQrdUuidPrefix + i);
          path.queryName = (String) dd.getFormValue(pathNamePrefix + i);
          path.pagingNumber = (String) dd.getFormValue(pathPagingNumberPrefix + i);
          add(path);
        }
      }
      String currentQrdUuid = (String) dd.getFormValue("currentQrdUuid");
      String currentQueryName = (String) dd.getFormValue("currentQueryName");
      String currentPagingNumber = (String) dd.getFormValue("currentPagingNumber");
      if (currentQrdUuid != null && currentQrdUuid.length() > 0) {
        PathItem path = new PathItem();
        path.qrdUuid = currentQrdUuid;
        path.queryName = currentQueryName;
        path.pagingNumber = currentPagingNumber;
        add(path);
      }
    }

    public String toHtml() {
      StringBuffer sb = new StringBuffer(size());
      for (int i = 0; i < size(); ++i) {
        sb.append("<a href=\"javascript:viewPathResult('" + i + "');\">"
            + get(i).queryName.substring(0, get(i).queryName.length() - 4) + "</a> &gt; ");
      }
      return sb.toString();
    }

    public String createHiddenFields() {
      StringBuffer sb = new StringBuffer(size());
      for (int i = 0; i < size(); ++i) {
        sb.append("<input type=hidden name=\"" + pathQrdUuidPrefix + i + "\" value=\""
            + get(i).qrdUuid + "\">");
        sb.append("<input type=hidden name=\"" + pathNamePrefix + i + "\" value=\""
            + get(i).queryName + "\">");
        sb.append("<input type=hidden name=\"" + pathPagingNumberPrefix + i + "\" value=\""
            + get(i).pagingNumber + "\">");
      }
      return sb.toString();
    }
  }

  public static class PathItem {
    String qrdUuid; // 
    String queryName;
    String pagingNumber; // 页码
  }

  public QueryState getQueryState(String qrdUuid) throws Exception {
    QueryResultDescription qrd = getResultMgr().findQrdByUuid(qrdUuid);
    return getQueryState(qrd);
  }

  private QueryState getQueryState(QueryResultDescription qrd) throws Exception {
    QueryState result = new QueryState();
    result.qrdUuid = qrd.getUuid();
    result.time = Long.toString((new Date().getTime() - qrd.getStartTime().getTime()) / 1000);
    result.state = qrd.getResultCount().intValue();
    result.errorMessage = qrd.getMessage();
    return result;
  }

  public static class QueryState {
    String qrdUuid;
    String time = "0"; // 执行时间, 以秒为单位.
    /** QueryResultDescription.RESULTCOUNT_RUNNING, ERROR, CANCEL */
    int state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
    String errorMessage;
  }

  /**
   * ajax同步调用, 由查询结果页面中的"重新查询"调用.
   * 
   * @param qrdUuid
   * @return
   * @throws Exception
   */
  public QueryState runQueryAgain(String qrdUuid) throws Exception {
    setSessionValues();
    QueryState result = new QueryState();
    result.qrdUuid = qrdUuid;
    QueryResultDescription qrd = null;
    qrd = getResultMgr().findQrdByUuid(qrdUuid);
    if (qrd == null) {
      result.state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
      result.errorMessage = "没有找到先前的查询结果.";
      return result;
    }
    try {
      QueryDefinition qd = getDefinitionMgr().getQueryDefinition(qrd);
      if (qd == null) {
        result.state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
        result.errorMessage = "查询定义文件不存在.";
        return result;
      }
      qd.setCriteria(qrd.getQueryCriteria().getSg());
      qrd.setQuery(qd);
      getQueryMgr().executeQuery(qrd, this);
      result = getQueryState(qrd.getUuid());
    } catch (MaxQueryException e) {
      result.state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
      result.errorMessage = "服务器忙(已达到最大查询数), 请稍后再试.";
    } catch (HibernateException e) {
      result.state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
      result.errorMessage = "无法连接数据库.";
    } catch (ParseException e) {
      result.state = QueryResultDescription.RESULTCOUNT_ERROR.intValue();
      result.errorMessage = "查询定义文件" + qrd.getQdName() + "有错误: " + e.getMessage();
    }
    return result;
  }

  /**
   * input form values
   * <li>qrd_uuid
   * <li>print_start 起始记录号
   * <li>print_limit 打印的记录数
   * <li>print_fields, 0,1,0,1的字符串. 0表示此列不打印,1表示打印.
   * <li>print_format 输出格式. 取值为htm, pdf, xls
   * 
   * @return
   * @throws Exception
   */
  public String printOld() throws Exception {
    // get input form values
    String qrdUuid = (String) dd.getFormValue("qrd_uuid");
    Integer start = (Integer) dd.validateFormValue("print_start", "PZInteger", false);
    if (start == null)
      start = new Integer(1);
    Integer limit = (Integer) dd.validateFormValue("print_limit", "PZInteger", false);
    if (limit == null)
      limit = new Integer(10000);
    if (limit.intValue() > 10000)
      limit = new Integer(10000);
    String[] fields = ((String) dd.getFormValue("print_fields")).split(",");
    String[] widthes = ((String) dd.getFormValue("print_widthes")).split(",");
    String format = (String) dd.getFormValue("print_format");
    if (format == null || format.length() == 0 || !"pdf".equals(format) && !"xls".equals(format))
      format = "htm";

    // 是横打还是竖打
    String print_style_direction = (String) dd.getFormValue("print_direction");
    if (print_style_direction == null)
      print_style_direction = "print_style_vertical";
    // 打印纸张的选择 a4或者a3 或者自定义
    int print_height = PaperDefinition.A4_HEIGHT;
    int print_width = PaperDefinition.A4_WIDTH;
    String printStyle = (String) dd.getFormValue("print_style");
    if ("print_style_customize".equals(printStyle)) {
      Integer print_width_customize = (Integer) dd.validateFormValue("print_width_customize",
          "PZInteger", true);
      Integer print_height_customize = (Integer) dd.validateFormValue("print_height_customize",
          "PZInteger", true);
      if ("print_style_vertical".equals(print_style_direction)) // 竖打
      {
        if (print_width_customize != null)
          print_width = print_width_customize.intValue();
        if (print_height_customize != null)
          print_height = print_height_customize.intValue();
      } else {
        if (print_width_customize != null)
          print_width = print_height_customize.intValue();
        if (print_height_customize != null)
          print_height = print_width_customize.intValue();
      }
    } else if ("print_style_a4".equals(printStyle)) {
      if ("print_style_vertical".equals(print_style_direction)) // 竖打
      {
        print_width = PaperDefinition.A4_WIDTH;
        print_height = PaperDefinition.A4_HEIGHT;
      } else {
        print_width = PaperDefinition.A4_HEIGHT;
        print_height = PaperDefinition.A4_WIDTH;
      }
    } else if ("print_style_a3".equals(printStyle)) {
      if ("print_style_vertical".equals(print_style_direction)) // 竖打
      {
        print_width = PaperDefinition.A3_WIDTH;
        print_height = PaperDefinition.A3_HEIGHT;
      }
      {
        print_width = PaperDefinition.A3_HEIGHT;
        print_height = PaperDefinition.A3_WIDTH;
      }
    }
    // create report elements
    Report report = new Report();
    QueryResultDescription qrd = getResultMgr().findQrdByUuid(qrdUuid);
    QueryDefinition qd = getDefinitionMgr().getQueryDefinition(qrd);
    qrd.setQuery(qd);
    // 设定打印尺寸
    report.getPaper().setPageHeight(print_height);
    report.getPaper().setPageWidth(print_width);
    // report.getPaper().setPageWidth(480);

    // prepare datasource
    SQLSubquery sq = new SQLSubquery();
    sq.addSelect("*");
    sq.addFrom(qrd.getTableName());
    for (int i = 0; i < qrd.getDisplayCriteria().getOrders().size(); ++i) {
      SQLOrder o = (SQLOrder) qrd.getDisplayCriteria().getOrders().get(i);
      sq.addOrder(o.getColumn(), o.getOrder());
    }
    Statement stmt = null;
    ResultSet rs = null;
    try {
      stmt = QueryResultSession.getSession().connection().createStatement();
      rs = stmt.executeQuery(sq.getSqlStatement());
      ResultSetMetaData md = rs.getMetaData();
      report.setDataSource(rs);
      String jrxml = qd.getName();
      jrxml = jrxml.replaceAll(".sql", ".jrxml");
      File jrxmlFile = new File(QTConstants.QDHOME, jrxml);
      if (jrxmlFile.exists()) {
        report.setDesignFile(jrxmlFile);
      } else {
        // prepare titles
        report.setReportTitle(qd.getName().substring(1, qd.getName().length() - 4));
        report.setReportSubtitle("查询时间: " + FormatSettings.SDFyMdHm.format(qrd.getStartTime())
            + "\n" + qrd.getInfo());
        // prepare field defintions
        List<FieldDefinition> fds = new ArrayList();
        SQLColumnList columns = qd.getColumns().getVisibleColumns();
        List resultNames = qd.getColumns().getResultTableVisibleColumnNames();
        for (int i = 0; i < fields.length; ++i) {
          if ("true".equals(fields[i])) {
            FieldDefinition fd = new FieldDefinition();
            SQLColumn c = columns.get(i);
            fd.setName((String) resultNames.get(i));
            fd.setTitle(c.getTitle());
            fd.setPattern(c.getPattern());
            fd.setWidth(Integer.parseInt(widthes[i]));
            fd.setValueClass(Class.forName(md.getColumnClassName(i + 2)));
            fd.setGAggregation(c.getGAggregation());
            fds.add(fd);
          }
        }
        report.setFieldDefinition(fds);
      }
      report.build(start.intValue(), limit.intValue());
      dd.getResponse().setContentType((String) getContentTypes().get(format));
      if ("htm".equals(format)) {
        dd.getResponse().setCharacterEncoding("utf-8");
        report.exportToHtml(dd.getResponse().getOutputStream());
      } else if ("pdf".equals(format)) {
        report.exportToPdf(dd.getResponse().getOutputStream());
      } else if ("xls".equals(format)) {
        report.exportToExcel(dd.getResponse().getOutputStream());
      }
    } catch (HibernateException e) {
      dd.addErrorText("服务器忙(已达到最大查询数), 请稍后再试.");
      dd.setWorkingTemplate("application/GeneralError.jsp");
      return ActionConstants.APPLICATIONFRAME;
    } finally {
      if (rs != null)
        rs.close();
      if (stmt != null)
        stmt.close();
    }
    return ActionConstants.DIRECT;
  }

  public String print() throws Exception {
    // get input form values
    Integer start = (Integer) dd.validateFormValue("print_start", "PZInteger", false);
    if (start == null)
      start = new Integer(1);
    Integer limit = (Integer) dd.validateFormValue("print_limit", "PZInteger", false);
    if (limit == null)
      limit = new Integer(10000);
    if (limit.intValue() > 10000)
      limit = new Integer(10000);
    String[] fields = ((String) dd.getFormValue("print_fields")).split(",");
    String format = (String) dd.getFormValue("print_format");
    if (format == null || format.length() == 0 || !"pdf".equals(format) && !"xls".equals(format))
      format = "htm";

    // 打印纸张的选择 a4或者a3 或者自定义. default a4.
    int print_height = PaperDefinition.A4HeightMM;
    int print_width = PaperDefinition.A4WidthMM;
    String printStyle = (String) dd.getFormValue("print_style");
    if ("print_style_customize".equals(printStyle)) {
      Integer print_width_customize = (Integer) dd.validateFormValue("print_width_customize",
          "PZInteger", true);
      Integer print_height_customize = (Integer) dd.validateFormValue("print_height_customize",
          "PZInteger", true);
      if (print_width_customize != null)
        print_width = print_width_customize.intValue();
      if (print_height_customize != null)
        print_height = print_height_customize.intValue();
    } else if ("print_style_a3".equals(printStyle)) {
      print_height = PaperDefinition.A3HeightMM;
      print_width = PaperDefinition.A3WidthMM;
    }

    // 是横打还是竖打
    String print_style_direction = (String) dd.getFormValue("print_direction");
    if (print_style_direction == null)
      print_style_direction = "print_style_vertical";
    if (!"print_style_vertical".equals(print_style_direction)) {
      int t = print_height;
      print_height = print_width;
      print_width = t;
    }
    print_height -= PaperDefinition.DefaultTopMargin + PaperDefinition.DefaultBottomMargin;

    // prepare visible fields
    boolean[] visibleFields = new boolean[fields.length];
    for (int i = 0; i < fields.length; ++i)
      visibleFields[i] = Boolean.parseBoolean(fields[i]);

    // prepare datasource
    resultQueryInternal(1, start.intValue(), limit.intValue());

    // prepare titles
    QueryResultDescription qrd = (QueryResultDescription) dd.get("qrd");
    String report_title = qrd.getQdName().substring(1, qrd.getQdName().length() - 4);
    String report_info = "查询时间: " + FormatSettings.SDFyMdHm.format(qrd.getStartTime())
        + "<br>查询条件: " + qrd.getInfo();

    if ("htm".equals(format)) {
      dd.put("report_title", report_title);
      dd.put("report_info", report_info);
      dd.put("print_height", new Integer(print_height));
      dd.put("print_width", new Integer(print_width));
      dd.put("visibleFields", visibleFields);
      dd.setWorkingTemplate(TEMPLATE_PRINT);
      return ActionConstants.APPLICATIONFRAME;
    } else { // xls
      List visibleColumns = (List) JspLib.getValue("visibleColumns", dd);
      List results = (List) JspLib.getValue("results", dd);
      List summary = (List) dd.get("summary");
      List names = (List) JspLib.getValue("names", dd);

      HttpServletResponse servletresponse = dd.getResponse();
      servletresponse.setContentType("application/vnd.ms-excel");
      servletresponse.setCharacterEncoding(StringUtil.ENCODING_CHARSET);
      servletresponse.setHeader("Content-Disposition", "attachment;filename="
          + StringUtil.encodeFileName(report_title.replaceAll("/", "-")) + ".xls");

      PrintStream out = new PrintStream(servletresponse.getOutputStream());
      out.println("<html>");
      out.println("<head>");
      out
          .println("<style>td{font-family:verdana;font-size:9pt;mso-number-format:\"\\@\";}</style>");
      out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=GBK\"/>");
      out.println("</head>");
      out.println("<body>");
      PrintTable p = new PrintTable();
      p.setOut(out);
      p.setVisibleColumns(visibleColumns);
      p.setResults(results);
      p.setSummary(summary);
      p.setNames(names);
      p.print(new Integer(print_width), report_title, report_info, visibleFields);
      out.println("</body></html>");
      out.flush();
      return ActionConstants.DIRECT;
    }
  } // 如果直接使用BuffaloSession.getXXX()的话, 由于是在QueryTrhead中调用getXXX(),

  public BResultPage queryList(BSQLSubquery bsq, int pageSize, int page) throws Exception {
    try {
      return this.query(bsq, pageSize, page);
    } catch (Exception e) {
      this.reportError("", e);
      throw e;
    }
  }

  public String listDef() throws Exception {
    dd.setWorkingTemplate(TEMPLATE_QUERYDEFLIST);
    return ActionConstants.APPLICATIONFRAME;
  }

  public String createDef() throws Exception {
    IQueryDef queryDef = getDefinitionMgr().createQueryDef(getCurrentDomain());
    dd.put("queryDef", queryDef);
    IBCartridgeMgr cartMgr = (IBCartridgeMgr) NamingMgr.getInstance().lookupMgr(
        IBCartridgeMgr.class);
    List<BCartFunctionView> cfvs = cartMgr.getAllFunctionViews();
    dd.put("functionViews", cfvs);
    dd.putFormValue(JspLib.ID_FORMSTATE, JspLib.VALUE_FORMSTATE_CREATE);
    dd.setWorkingTemplate(TEMPLATE_QUERYDEFCREATE);
    return ActionConstants.APPLICATIONFRAME;
  }

  public String viewDef() throws Exception {
    String queryDefUuid = (String) dd.getFormValue("queryDef_uuid");
    if (queryDefUuid == null)
      throw new Exception("缺少必要的参数：queryDef_uuid。");
    IQueryDef queryDef = getDefinitionMgr().getQueryDef(queryDefUuid);
    if (queryDef == null)
      throw new Exception("找不到指定的查询定义(uuid=" + queryDefUuid + ")。");
    if (!queryDef.getFile().exists())
      throw new Exception("找不到指定的查询文件：" + queryDef.getFullFilename());
    dd.getResponse().setContentType("text/plain");
    dd.getResponse().setCharacterEncoding(StringUtil.ENCODING_CHARSET);
    ServletOutputStream out = dd.getResponse().getOutputStream();
    FileInputStream ins = new FileInputStream(queryDef.getFile());
    String header = "查询名：" + queryDef.getName() + "\r\n路  径：" + queryDef.getLocation() + "\r\n文件名："
        + queryDef.getFullFilename()
        + "\r\n文件内容：\r\n======================================================\r\n";
    String tail = "";
    out.write(header.getBytes());
    byte abyte0[] = new byte[2048];
    int bytesRead, len = 0;
    while (-1 != (bytesRead = ins.read(abyte0, 0, abyte0.length))) {
      len += bytesRead;
      out.write(abyte0, 0, bytesRead);
    }
    out.write(tail.getBytes());
    dd.getResponse().setContentLength(len + header.length() + tail.length());
    out.flush();
    return ActionConstants.DIRECT;
  }

  public void removeDefs(String uuid, long oca) throws Exception {
    Transaction tx = HibernateSession.getSession().beginTransaction();
    try {
      IQueryDef queryDef = getDefinitionMgr().getQueryDef(uuid);
      if (queryDef == null)
        throw new Exception("找不到指定的查询定义(uuid=" + uuid + ")。");
      // 通知外部系统删除权限
      ExternalRequestHandler.removeQueryDef(BuffaloSession.getSession(), queryDef.getUuid(),
          getCurrentUser().getUuid());
      getDefinitionMgr().removeDef(queryDef, new OperateContext(getCurrentUser()));
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      this.reportError("", e);
      throw e;
    }
  }

  public void removeResults(String uuid, long oca) throws Exception {
    Transaction tx = HibernateSession.getSession().beginTransaction();
    try {
      QueryResultDescription qrd = getResultMgr().findQrdByUuid(uuid);
      if (qrd != null && (!qrd.isEmpty())) {
        getResultMgr().removeQrd(qrd);
        if (qrd.getResultCount().intValue() != -2 && qrd.getResultCount().intValue() != -3) {
          String tableName = qrd.getTableName();
          getQueryMgr().deleteTable(tableName);
        }
      }
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      this.reportError("", e);
      throw e;
    }
  }

  public void cancelQueries(String uuid, long oca) throws Exception {
    Transaction tx = HibernateSession.getSession().beginTransaction();
    try {
      getQueryMgr().cancelQuery(uuid);
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      this.reportError("", e);
      throw e;
    }
  }

  public String saveDef() throws Exception {
    File file = (File) dd.getFormValue("query_file");
    String location = (String) dd.getFormValue("query_location");
    String usefr3 = (String) dd.getFormValue("query_usefr3");
    String domainUuid = (String) dd.getFormValue("query_domain_uuid");
    IDomainMgr domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    IDomain domain = domainMgr.getDomain(domainUuid);
    String folder = "/" + location;
    if (file == null) {
      dd.addErrorText("请选择导入的文件。");
      return createDef();
    }
    if (!dd.isFormValid())
      return createDef();
    String fileName = StringUtil.extractFileName(file.getName());
    String name = null;
    StringTokenizer st = new StringTokenizer(fileName, ".");
    if (st.countTokens() > 0) {
      while (st.hasMoreElements()) {
        name = st.nextToken();
      }
    }
    if (!name.equals("sql")) {
      dd.addErrorText("你要导入的不是.sql文件，请重新导入!");
      return createDef();
    }
    List<String> cfvUuids = new ArrayList<String>();
    Iterator cfvs = dd.createFormSelectedValuesIterator("cfv_uuid");
    while (cfvs.hasNext()) {
      String cfvUuid = (String) cfvs.next();
      cfvUuids.add(cfvUuid);
    }
    if (cfvUuids.size() == 0) {
      dd.addErrorText("查询定义至少应该具有一个相关的功能视图。");
      return createDef();
    }

    FileInputStream in = new FileInputStream(file);
    Transaction tx = HibernateSession.getSession().beginTransaction();
    try {
      File serverFile = getDefinitionMgr().saveFile(folder.toUpperCase(), fileName, in,
          getCurrentUser());
      IQueryDef qd = getDefinitionMgr().getQueryDefByFile(location, serverFile.getName());
      if (qd == null) {
        IQueryDef queryDef = getDefinitionMgr().createQueryDef(domain);
        queryDef.setName(fileName.replace(".sql", ""));
        queryDef.setLocation(location);
        queryDef.setFilename(serverFile.getName());
        getDefinitionMgr().saveQueryDef(queryDef, cfvUuids, new OperateContext(getCurrentUser()));
        // 通知外部系统创建权限
        ExternalRequestHandler.saveQueryDef(dd.getSession(), queryDef.getUuid(), queryDef
            .getPermission(), getCurrentUser().getUuid());
        // 复制默认模版
        if ("是".equals(usefr3) && !queryDef.getTemplateFile().exists()) {
          File emptyTemplate = new File(dd.getSession().getServletContext().getRealPath(
              "static/rumba/activex/empty.fr3"));
          FileInputStream fi = new FileInputStream(emptyTemplate);
          FileOutputStream fo = new FileOutputStream(queryDef.getTemplateFile());
          StreamUtils.copy(fi, fo);
        }
      }
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      dd.addErrorText("保存查询定义出错。" + e.getMessage());
      return createDef();
    } finally {
      file.delete();
    }
    dd.addHint("查询定义已保存。");
    return listDef();
  }

  public String filterMyQuerys() throws Exception {
    QueryResultFilter filter = getQueryResultFilter();
    dd.put("filter", filter);
    dd.setWorkingTemplate(TEMPLATE_MYQUERYSFILTER);
    return ActionConstants.APPLICATIONFRAME;
  }

  public String filterAllQuerys() throws Exception {
    QueryResultFilter filter = getQueryResultFilter();
    dd.put("filter", filter);
    dd.setWorkingTemplate(TEMPLATE_ALLQUERYSFILTER);
    return ActionConstants.APPLICATIONFRAME;
  }

  private QueryResultFilter getQueryResultFilter() throws Exception {
    QueryResultFilter filter = new QueryResultFilter();
    filter.setUserCodeLike((String) dd.getFormValue("filter_userCode"));
    filter.setQdNameLike((String) dd.getFormValue("filter_qdName"));
    filter.setState((String) dd.getFormValue("filter_state"));
    filter
        .setStartTimeFrom((this.parseDateOrTime((String) dd.getFormValue("filter_startTimeFrom"))));
    filter.setStartTimeTo(this.parseDateOrTime((String) dd.getFormValue("filter_startTimeTo")));
    return filter;
  }

  private Date parseDateOrTime(String s) throws Exception {
    Date result = null;
    if (s == null || s.length() == 0)
      return result;
    try {
      result = FormatSettings.SDFyMdHms.parse(s);
    } catch (Exception e) {
      try {
        result = FormatSettings.SDFyMd.parse(s);
      } catch (Exception e2) {
      }
    }
    return result;
  }

  public String printOptions() throws Exception {
    String qrdUuid = (String) dd.getFormValue("qrd_uuid");
    QueryResultDescription qrd = getResultMgr().findQrdByUuid(qrdUuid);
    QueryDefinition qd = getDefinitionMgr().getQueryDefinition(qrd);
    dd.put("qrd", qrd);
    dd.put("qd", qd);
    return TEMPLATE_PRINTOPTIONS;
  }

  // 线程上下文不是处理Buffalo请求的线程, 得到的东东是空的. 因此要在处理Buffalo请求的线程中获取getXXX()的值并记录下来.
  // 一并地, 把dd中的这些内容也记录下来.
  private IDomain svCurrentDomain;
  private IUser svCurrentUser;
  private Hashtable svSessionValues;

  private void setSessionValues() {
    if (dd != null) {
      svCurrentDomain = dd.getCurrentDomain();
      svCurrentUser = dd.getCurrentUser();
      svSessionValues = dd.getSessionValues();
    } else {
      svCurrentDomain = BuffaloSession.getCurrentDomain();
      svCurrentUser = BuffaloSession.getCurrentUser();
      svSessionValues = BuffaloSession.getSessionValues();
    }
  }

  public IDomain getCurrentDomain() {
    if (svCurrentDomain == null)
      setSessionValues();
    return svCurrentDomain;
  }

  public IUser getCurrentUser() {
    if (svCurrentUser == null)
      setSessionValues();
    return svCurrentUser;
  }

  public Object getSessionValue(String key) {
    if (svSessionValues == null)
      setSessionValues();
    return svSessionValues.get(key);
  }

}
